home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / plugin / gamelib / subdiv_mesh.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-21  |  9.7 KB  |  424 lines

  1. #include "..\..\lib\Fly3D.h"
  2. #include "gamelib.h"
  3.  
  4. void subdiv_mesh::init()
  5. {
  6.     subdiv();
  7. }
  8.  
  9. void subdiv_mesh::draw()
  10. {
  11.     if (divmesh)
  12.     {
  13.         if (flyengine->hwlights)
  14.             {
  15.             divmesh->color.vec(1,1,1,1);
  16.             dynlights.init_draw(this);
  17.             }
  18.         else if (node)
  19.             {
  20.             divmesh->color=node->color+dynlight;
  21.             dynlight.null();
  22.             }
  23.         glPushMatrix();
  24.         glTranslatef(pos.x,pos.y,pos.z);
  25.         glMultMatrixf((float *)&mat);
  26.         divmesh->draw();
  27.         glPopMatrix();
  28.         if (flyengine->hwlights)
  29.             dynlights.end_draw();
  30.     }
  31. }
  32.  
  33. bsp_object *subdiv_mesh::clone()
  34. {
  35.     subdiv_mesh *tmp=new subdiv_mesh;
  36.     *tmp=*this;
  37.     tmp->source=this;
  38.     return tmp;
  39. }
  40.  
  41. int subdiv_mesh::get_custom_param_desc(int i,param_desc *pd)
  42. {
  43.     if (pd!=0)
  44.     switch(i)
  45.     {
  46.     case 0:
  47.         pd->type='3';
  48.         pd->data=&basemesh;
  49.         strcpy(pd->name,"basemesh");
  50.         break;
  51.     case 1:
  52.         pd->type='i';
  53.         pd->data=&nsubdiv;
  54.         strcpy(pd->name,"nsubdiv");
  55.         break;
  56.     case 2:
  57.         pd->type='i';
  58.         pd->data=&mode;
  59.         strcpy(pd->name,"mode");
  60.         break;
  61.     }
  62.     return 3;
  63. }
  64.  
  65. int subdiv_mesh::message(vector& p,float rad,int msg,int param,void *data)
  66. {
  67.     if (msg==FLYOBJM_CHANGEPARAM && param>=0)
  68.         init();
  69.     else
  70.     if (flyengine->hwlights)
  71.         if (msg==FLYOBJM_ILLUM || msg==FLYOBJM_DYNILLUM)
  72.             dynlights.add_light(p,*((vector *)data),rad);
  73.         else ;
  74.     else if (msg==FLYOBJM_ILLUM)
  75.     {
  76.         float fac=(p-pos).length()/rad;
  77.         if (fac<1.0f)
  78.             dynlight+=*((vector *)data)*(1.0f-fac);
  79.     }
  80.  
  81.     return 0;
  82. }
  83.  
  84. void subdiv_mesh::reset()
  85. {
  86.     if (divmesh) delete divmesh; 
  87.     if (edges) delete edges;
  88.     if (edgefaces) delete edgefaces;
  89.     divmesh=0;
  90.     edges=0;
  91.     edgefaces=0;
  92.     nedges=0;
  93. }
  94.  
  95. void subdiv_mesh::subdiv()
  96. {
  97.     reset();
  98.     if (source==0 || basemesh==0)
  99.         return;
  100.  
  101.     int i; 
  102.     mesh *m1,*m2;
  103.     m1=basemesh->clone();
  104.     pos=basemesh->pivotpos;
  105.  
  106.     // for each subdiv step, subdivide mesh m1 into mesh m2
  107.     for( i=0;i<nsubdiv;i++ )
  108.     {
  109.     reset();
  110.     // create mesh
  111.     m2=new mesh;
  112.     // lists all edges for mesh m1
  113.     build_edge_list(m1); 
  114.     // add one vertex at each edge in mesh m2
  115.     add_vertices(m1,m2);
  116.     // add 3 faces at each original face
  117.     add_faces(m1,m2);     
  118.  
  119.     // delete mesh m1 and replace it with mesh m2
  120.     delete m1;
  121.     m1=m2;
  122.     }
  123.  
  124.     // store last subdivided mesh
  125.     divmesh=m1;
  126.     // compute mesh normals
  127.     divmesh->compute_normals(MESH_FACENORM|MESH_VERTNORM|MESH_BBOX);
  128. }
  129.  
  130. int subdiv_mesh::get_edge(int v1,int v2)
  131. {
  132.     // returns index into edges list for edge (v1,v2)
  133.     int i;
  134.     for( i=0;i<nedges;i++ )
  135.         if ((edges[i*2]==v1 && edges[i*2+1]==v2) ||
  136.             (edges[i*2+1]==v1 && edges[i*2]==v2))
  137.             break;
  138.     if (i==nedges)
  139.         return -1;
  140.     return i;
  141. }
  142.  
  143. int subdiv_mesh::get_valence(int v1)
  144. {
  145.     // returns the number of edges using vertex v1
  146.     int i,count=0;
  147.     for( i=0;i<nedges;i++ )
  148.         if (edges[i*2]==v1 || edges[i*2+1]==v1)
  149.             count++;
  150.     return count;
  151. }
  152.  
  153. void subdiv_mesh::build_edge_list(mesh *m1)
  154. {
  155.     // build the edges list adding all edges from 
  156.     // all faces (faces can share edges)
  157.     int i,j;
  158.     for( i=0;i<m1->nf;i++ )
  159.         for( j=0;j<3;j++ )
  160.             add_edge(
  161.                 m1->localfaces[i].vert[j]-m1->vert,
  162.                 m1->localfaces[i].vert[(j+1)%3]-m1->vert,
  163.                 i);
  164. }
  165.  
  166. void subdiv_mesh::add_edge(int v1,int v2,int f)
  167. {
  168.     // adds a new edge to the edges list
  169.  
  170.     int i=get_edge(v1,v2);
  171.     if (i>=0)
  172.         // edge already exists, just store face index
  173.         edgefaces[i*2+1]=f;
  174.     else
  175.     {
  176.     // add two new entries to the lists
  177.     int *tmp;
  178.     tmp=new int [nedges*2+2];
  179.     memcpy(tmp,edges,sizeof(int)*2*nedges);
  180.     if (edges) delete edges;
  181.     edges=tmp;
  182.     tmp=new int [nedges*2+2];
  183.     memcpy(tmp,edgefaces,sizeof(int)*2*nedges);
  184.     if (edgefaces) delete edgefaces;
  185.     edgefaces=tmp;
  186.  
  187.     // store edge and face
  188.     edges[nedges*2]=v1;
  189.     edges[nedges*2+1]=v2;
  190.     edgefaces[nedges*2]=f;
  191.     edgefaces[nedges*2+1]=-1;
  192.     nedges++;
  193.     }
  194. }
  195.  
  196. void subdiv_mesh::add_vertices(mesh *m1,mesh *m2)
  197. {
  198.     int a,i,j,k,n,v0[2],v1[2],v2[4],e[4],f0[2],f1[4],valence[2];
  199.  
  200.     // alloc vertices for destination mesh m2
  201.     m2->nv=nedges + m1->nv;
  202.     m2->set_numverts(m2->nv);
  203.     // copy mesh m1 vertices into mesh m2
  204.     memcpy(m2->vert,m1->vert,sizeof(vector)*m1->nv);
  205.  
  206.     // for all edges from mesh m1
  207.     for( i=0;i<nedges;i++ )
  208.     {
  209.         // find the edge vertices
  210.         v0[0]=edges[i*2];
  211.         v0[1]=edges[i*2+1];
  212.         // find the faces sharing this edge
  213.         f0[0]=edgefaces[i*2];
  214.         f0[1]=edgefaces[i*2+1];
  215.  
  216.         // place vertex in the center of the edge
  217.         m2->vert[m1->nv+i]=(m1->vert[v0[0]]+m1->vert[v0[1]])*0.5f;
  218.  
  219.         if (mode)
  220.         {
  221.         valence[0]=get_valence(v0[0]);
  222.         valence[1]=get_valence(v0[1]);
  223.         if (valence[0]<5 || valence[1]<5)
  224.             {
  225.             vector disp[2];
  226.             for( j=0;j<2;j++ )
  227.                 if (valence[j]==3 || valence[j]==4)
  228.                 {
  229.                     disp[j]=m1->vert[v0[j]]*(3.0f/4.0f);
  230.                     n=0;
  231.                     if (valence[j]==3)
  232.                     {
  233.                          for( k=0;k<nedges;k++ )
  234.                              if (edges[k*2]==v0[j] || edges[k*2+1]==v0[j])
  235.                              {
  236.                                  if (edges[k*2]==v0[j])
  237.                                      a=edges[k*2+1];
  238.                                  else a=edges[k*2];
  239.                                  if (a==v0[!j])
  240.                                      disp[j]+=m1->vert[a]*(5.0f/12.0f);
  241.                                  else 
  242.                                      disp[j]-=m1->vert[a]*(1.0f/12.0f);
  243.                                  n++;
  244.                                  if (n==3)
  245.                                      break;
  246.                              }
  247.                      }
  248.                      else
  249.                      {
  250.                         int vv[4];
  251.                         for( k=0;k<nedges;k++ )
  252.                         if (edges[k*2]==v0[j] || edges[k*2+1]==v0[j])
  253.                         {
  254.                             if (edges[k*2]==v0[j])
  255.                                 vv[n++]=edges[k*2+1];
  256.                             else vv[n++]=edges[k*2];
  257.                             if (n==4)
  258.                                 break;
  259.                         }
  260.  
  261.                         if (f0[1]==-1)
  262.                         {
  263.                             continue;
  264.                             // -1/16 9/16 9/16 -1/16
  265.                         }
  266.                         else
  267.                         {
  268.                             for( k=0;k<4;k++ )
  269.                                 if (vv[k]==v0[!j])
  270.                                     disp[j]+=m1->vert[vv[k]]*(3.0f/8.0f);
  271.                                 else
  272.                                 {
  273.                                     for( a=0;a<3;a++ )
  274.                                         if (vv[k]==m1->localfaces[f0[0]].vert[a]-m1->vert ||
  275.                                             vv[k]==m1->localfaces[f0[1]].vert[a]-m1->vert)
  276.                                             break;
  277.                                     if (a==3)
  278.                                         disp[j]-=m1->vert[vv[k]]*(1.0f/8.0f);
  279.                                 }
  280.                         }
  281.                      }
  282.                 }
  283.  
  284.             if ((valence[0]==3 || valence[0]==4)&&
  285.                 (valence[1]==3 || valence[1]==4))
  286.                 m2->vert[m1->nv+i]=(disp[0]+disp[1])*0.5;
  287.             else if (valence[0]==3 || valence[0]==4)
  288.                     m2->vert[m1->nv+i]=disp[0];
  289.             else if (valence[1]==3 || valence[1]==4)
  290.                     m2->vert[m1->nv+i]=disp[1];
  291.  
  292.             continue;
  293.             }
  294.         }
  295.  
  296.         if (f0[1]==-1)
  297.             continue;
  298.  
  299.         // compute the two v1 vertices
  300.         v1[0]=v1[1]=-1;
  301.         for( j=0;j<2;j++ )
  302.             for( k=0;k<3;k++ )
  303.             {
  304.             a=m1->localfaces[f0[j]].vert[k]-m1->vert;
  305.             if (a!=v0[0] && a!=v0[1])
  306.                 {
  307.                 v1[j]=a;
  308.                 break;
  309.                 }
  310.             }
  311.  
  312.         // compute the four e edges
  313.         e[0]=get_edge(v0[0],v1[0]);
  314.         e[1]=get_edge(v0[0],v1[1]);
  315.         e[2]=get_edge(v0[1],v1[0]);
  316.         e[3]=get_edge(v0[1],v1[1]);
  317.         if (e[0]==-1 || e[1]==-1 || e[2]==-1 || e[3]==-1)
  318.             continue;
  319.  
  320.         // compute the four f faces
  321.         for( j=0;j<4;j++ )
  322.             if (edgefaces[e[j]*2]!=edgefaces[i*2] && 
  323.                 edgefaces[e[j]*2]!=edgefaces[i*2+1])
  324.                 f1[j]=edgefaces[e[j]*2];
  325.             else f1[j]=edgefaces[e[j]*2+1];
  326.         if (f1[0]==-1 || f1[1]==-1 || f1[2]==-1 || f1[3]==-1)
  327.             continue;
  328.  
  329.         // compute the four v2 vertices
  330.         v2[0]=v2[1]=v2[2]=v2[3]=-1;
  331.         for( j=0;j<4;j++ )
  332.         for( k=0;k<3;k++ )
  333.             {
  334.             a=m1->localfaces[f1[j]].vert[k]-m1->vert;
  335.             if (a!=edges[e[j]*2] && a!=edges[e[j]*2+1])
  336.                 {
  337.                 v2[j]=a;
  338.                 break;
  339.                 }
  340.             }
  341.         if (v2[0]==-1 || v2[1]==-1 || v2[2]==-1 || v2[3]==-1)
  342.             continue;
  343.         
  344.         // move vertex based on v1 and v2 and subdivfactor
  345.         m2->vert[m1->nv+i]+=
  346.             (m1->vert[v1[0]]+m1->vert[v1[1]])*(1.0f/8.0f)+
  347.             (m1->vert[v2[0]]+m1->vert[v2[1]]+m1->vert[v2[2]]+m1->vert[v2[3]])*(-1.0f/16.0f);
  348.     }
  349. }
  350.  
  351. void subdiv_mesh::add_faces(mesh *m1,mesh *m2)
  352. {
  353.     int i,j,k,e[3];
  354.     float euv[3][2];
  355.  
  356.     // alloc faces for destination mesh m2
  357.     m2->nf=m1->nf*4;
  358.     m2->set_numfaces(m2->nf,1);
  359.     for( i=0;i<m2->nf;i++ )
  360.         m2->faces[i]=&m2->localfaces[i];
  361.  
  362.     // for all faces in m1
  363.     for( i=j=0;i<m1->nf;i++ )
  364.     {
  365.     // find edges for mesh m1 face i and 
  366.     // compute the face edges center texture coordinates
  367.     for( k=0;k<3;k++ )
  368.         {
  369.         e[k]=get_edge(
  370.             m1->localfaces[i].vert[k]-m1->vert,
  371.             m1->localfaces[i].vert[(k+1)%3]-m1->vert);
  372.         euv[k][0]=0.5f*(m1->localfaces[i].uv[k][0]+m1->localfaces[i].uv[(k+1)%3][0]);
  373.         euv[k][1]=0.5f*(m1->localfaces[i].uv[k][1]+m1->localfaces[i].uv[(k+1)%3][1]);
  374.         }
  375.  
  376.     // create face f1
  377.     m2->localfaces[j]=m1->localfaces[i];
  378.     m2->localfaces[j].vert[0]=&m2->vert[m1->localfaces[i].vert[0]-m1->vert];
  379.     m2->localfaces[j].vert[1]=&m2->vert[e[0]+m1->nv];
  380.     m2->localfaces[j].vert[2]=&m2->vert[e[2]+m1->nv];
  381.     m2->localfaces[j].uv[1][0]=euv[0][0];
  382.     m2->localfaces[j].uv[1][1]=euv[0][1];
  383.     m2->localfaces[j].uv[2][0]=euv[2][0];
  384.     m2->localfaces[j].uv[2][1]=euv[2][1];
  385.     j++;
  386.  
  387.     // create face f2
  388.     m2->localfaces[j]=m1->localfaces[i];
  389.     m2->localfaces[j].vert[0]=&m2->vert[e[0]+m1->nv];
  390.     m2->localfaces[j].vert[1]=&m2->vert[m1->localfaces[i].vert[1]-m1->vert];
  391.     m2->localfaces[j].vert[2]=&m2->vert[e[1]+m1->nv];
  392.     m2->localfaces[j].uv[0][0]=euv[0][0];
  393.     m2->localfaces[j].uv[0][1]=euv[0][1];
  394.     m2->localfaces[j].uv[2][0]=euv[1][0];
  395.     m2->localfaces[j].uv[2][1]=euv[1][1];
  396.     j++;
  397.  
  398.     // create face f3
  399.     m2->localfaces[j]=m1->localfaces[i];
  400.     m2->localfaces[j].vert[0]=&m2->vert[e[2]+m1->nv];
  401.     m2->localfaces[j].vert[1]=&m2->vert[e[1]+m1->nv];
  402.     m2->localfaces[j].vert[2]=&m2->vert[m1->localfaces[i].vert[2]-m1->vert];
  403.     m2->localfaces[j].uv[0][0]=euv[2][0];
  404.     m2->localfaces[j].uv[0][1]=euv[2][1];
  405.     m2->localfaces[j].uv[1][0]=euv[1][0];
  406.     m2->localfaces[j].uv[1][1]=euv[1][1];
  407.     j++;
  408.  
  409.     // create face f4
  410.     m2->localfaces[j]=m1->localfaces[i];
  411.     m2->localfaces[j].vert[0]=&m2->vert[e[0]+m1->nv];
  412.     m2->localfaces[j].vert[1]=&m2->vert[e[1]+m1->nv];
  413.     m2->localfaces[j].vert[2]=&m2->vert[e[2]+m1->nv];
  414.     m2->localfaces[j].uv[0][0]=euv[0][0];
  415.     m2->localfaces[j].uv[0][1]=euv[0][1];
  416.     m2->localfaces[j].uv[1][0]=euv[1][0];
  417.     m2->localfaces[j].uv[1][1]=euv[1][1];
  418.     m2->localfaces[j].uv[2][0]=euv[2][0];
  419.     m2->localfaces[j].uv[2][1]=euv[2][1];
  420.     j++;
  421.     }
  422. }
  423.  
  424.